#pragma once
#include "DynamicList.h"

////////////////////////////////////
///   class Stack: Declaration   ///
////////////////////////////////////

template <class Type>
class Stack
{
public:
	virtual ~Stack();

	void Push(Type *i_Value);
	Type *Peek();
	Type *Pop();
	bool IsEmpty() const;
	void ClearStack();	

	int ToArray(Type *&i_Array) const;

private:
	CDynamicList<Type> m_List;
};

///////////////////////////////////////
///   class Stack: implementation   ///
///////////////////////////////////////

template <class Type>
Stack<Type>::~Stack()
{
	this->m_List.ClearList();
}

template <class Type>
void Stack<Type>::Push(Type *i_Value)
{
	const bool v_FreeMemory = true;

	this->m_List.AddItemToFirst(i_Value, !v_FreeMemory);
	this->m_List.SelectFirst();
}

template <class Type>
Type *Stack<Type>::Peek()
{
	Type *value = NULL;

	if (this->m_List.ListCount() > 0)
	{
		value = this->m_List.GetValue();
	}

	return value;
}

template <class Type>
Type *Stack<Type>::Pop()
{
	Type *value = this->Peek();

	if (value)
	{
		this->m_List.RemoveCurrentItem();
		this->m_List.SelectFirst();
	}

	return value;
}

template <class Type>
bool Stack<Type>::IsEmpty() const
{
	return this->m_List.ListCount() == 0;
}

template <class Type>
void Stack<Type>::ClearStack()
{
	this->m_List.ClearList();
}

template <class Type>
int Stack<Type>::ToArray(Type *&i_Array) const
{
	return this->m_List.ToArray(i_Array);
}
